#include "my_jpeg.h"


//++++++++++++++++++++++++++++++++++显示JPG+++++++++++++++++++++++++++++

//错误处理函数
METHODDEF(void)
my_error_exit (j_common_ptr cinfo)
{
  /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
  my_error_ptr myerr = (my_error_ptr) cinfo->err;

  /* Always display the message. */
  /* We could postpone this until after returning, if we chose. */
  (*cinfo->err->output_message) (cinfo);

  /* Return control to the setjmp point */
  longjmp(myerr->setjmp_buffer, 1);
}


/*
 * Sample routine for JPEG decompression.  We assume that the source file name
 * is passed in.  We want to return 1 on success, 0 on error.
 */

//读取JPEG 文件     读取JPEG的数据转换成BMP数据GLOBAL  -》 声明为外部函数
// read_JPEG_file 显示一张jpeg图片
// filename  需要显示的jpeg图片名
// lcdmem    映射内存的首地址
GLOBAL(int) read_JPEG_file (char * filename,int *lcdmem)  //需要一个文件名 
{
  //定义一个JPEG解码信息结构体
  struct jpeg_decompress_struct cinfo;
 
  //定义一个错误信息结构体
  struct my_error_mgr jerr;
  /* More stuff */
  FILE * infile;        /*定义源文件指针 标准IO的*/
  JSAMPARRAY buffer;        /*输出行缓冲*/
  int row_stride;       /*输出行缓冲的宽度 */

  //打开源文件 
  if ((infile = fopen(filename, "rb")) == NULL) {
    fprintf(stderr, "can't open %s\n", filename);
    return 0;
  }

  /* 第一步：初始化JPEG解码对象,同时判断传入的图片是否是jpeg图片*/
  cinfo.err = jpeg_std_error(&jerr.pub);
  jerr.pub.error_exit = my_error_exit;
  if (setjmp(jerr.setjmp_buffer)) {
    jpeg_destroy_decompress(&cinfo);
    fclose(infile);
    return 0;
  }
  
  /*现在我们可以初始化解码对象了*/
  jpeg_create_decompress(&cinfo);

  /*把源文件与解码对象关联起来 */
  jpeg_stdio_src(&cinfo, infile);

  /*读取JPEG图片的头数据*/
  (void) jpeg_read_header(&cinfo, TRUE);
 
  /*开始解码*/
  (void) jpeg_start_decompress(&cinfo);
 
  //得到一行数据所占用的字节数 
  row_stride = cinfo.output_width * cinfo.output_components;
  
  printf("jpeg图片 宽：%d  高：%d\n ", cinfo.output_width,cinfo.output_height);
  /*根据行字节数去分配堆空间*/
  buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
   
  char *p=NULL;   
  
  //LCD屏幕是 ARGB 格式
  unsigned char r=0;
  unsigned char g=0;
  unsigned char b=0; 
  unsigned char a=0; 
      
  int color=0;    
  char *q = (char *)&color; 
  
  int x=0,y=0; 

  //重点 重点 重重点！！！！ 解码就在这里进行了 上面的都是准备工作！！
  while (cinfo.output_scanline < cinfo.output_height)
  {
      
    //解码一行JPEG图形的数据变成bmp数据并存放到buffer 中 
    (void) jpeg_read_scanlines(&cinfo, buffer, 1);
    
    p = buffer[0]; 
    
    y  = cinfo.output_scanline; 
     
    //取出RGB数据 646 370
    for(x=0;x<cinfo.output_width;x++)
    {
        
        r = *p++;
        g = *p++; 
        b = *p++; 
        a = 0;  
         
      //赋值到color的地址上  
       *q  = b; 
       *(q+1) = g; 
       *(q+2) = r; 
       *(q+3) = a; 
       
       if(x < cinfo.output_width && y < cinfo.output_height )
       {
          //直接显示color  
          *(lcdmem+y*800+x) = color;
       }
    }
    /*输出解码后的一行数据*/
   // put_scanline_someplace(buffer[0], row_stride); 
  }
   //结束解码对象
  (void) jpeg_finish_decompress(&cinfo);

  //销毁解码对象
  jpeg_destroy_decompress(&cinfo);

  //关闭文件
  fclose(infile);

  return 1;
}


//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++